www.gusucode.com > VC++ 实现类似Winrar一样带有图标的右键菜单-源码程序 > VC++ 实现类似Winrar一样带有图标的右键菜单-源码程序/code/IconExtract/IconExtractObj.cpp
//Download by http://www.NewXing.com // IconExtractObj.cpp : Implementation of CIconExtractObj #include "stdafx.h" #include "IconExtract.h" #include "IconExtractObj.h" ///////////////////////////////////////////////////////////////////////////// // CIconExtractObj // IShellExtInit HRESULT CIconExtractObj::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID) { FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stg = { TYMED_HGLOBAL }; HDROP hDrop; // Look for CF_HDROP data in the data object. if(FAILED(pDataObj->GetData(&fmt, &stg))) { // Nope! Return an "invalid argument" error back to Explorer. return E_INVALIDARG; } // Get a pointer to the actual data. hDrop = (HDROP)GlobalLock(stg.hGlobal); // Make sure it worked. if(NULL == hDrop) { return E_INVALIDARG; } // Sanity check, make sure there is at least one filename. UINT uNumFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); if(0 == uNumFiles) { GlobalUnlock(stg.hGlobal); ReleaseStgMedium (&stg); return E_INVALIDARG; } HRESULT hr = S_OK; // Get the name of the first file and store it in our member variable m_szFile. if(0 == DragQueryFile(hDrop, 0, m_szFile, MAX_PATH)) hr = E_INVALIDARG; GlobalUnlock(stg.hGlobal); ReleaseStgMedium(&stg); return hr; } // IContextMenu HRESULT CIconExtractObj::QueryContextMenu(HMENU hmenu, UINT uMenuIndex, UINT uCmdID, UINT uidLastCmd, UINT uFlags) { //If the flags include CMF_DEFAULTONLY then we shouldn't do anything. if(uFlags & CMF_DEFAULTONLY) return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); int nMenus = 0; //The number of icons in the file int nIcons = (int)ExtractIconEx(m_szFile, -1, NULL, NULL, 0); if(nIcons > 0) { InsertMenu(hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++, _T("Extract &Large Icon")); if(NULL != m_hExtractBmpL) SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_hExtractBmpL, NULL); uMenuIndex++; InsertMenu(hmenu, uMenuIndex, MF_STRING | MF_BYPOSITION, uCmdID++, _T("Extract &Small Icon")); if(NULL != m_hExtractBmpS) SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_hExtractBmpS, NULL); uMenuIndex++; nMenus = 2; } return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, nMenus); } HRESULT CIconExtractObj::GetCommandString(UINT idCmd, UINT uFlags, UINT* pwReserved, LPSTR pszName, UINT cchMax) { USES_CONVERSION; // Check idCmd, it must be 0 or 1 since we have two menu items if(idCmd > 1) return E_INVALIDARG; LPCTSTR szPrompt; if(uFlags & GCS_HELPTEXT) { switch(idCmd) { case 0: szPrompt = _T("Icon Extractor, Extracting the Large Icon"); break; case 1: szPrompt = _T("Icon Extractor, Extracting the Small Icon"); break; default: return E_INVALIDARG; break; } if(uFlags & GCS_UNICODE) { // We need to cast pszName to a Unicode string, and then use the Unicode string copy API. lstrcpynW((LPWSTR)pszName, T2CW(szPrompt), cchMax); } else { // Use the ANSI string copy API to return the help string. lstrcpynA(pszName, T2CA(szPrompt), cchMax); } return S_OK; } return E_INVALIDARG; } HRESULT CIconExtractObj::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo) { // If lpVerb really points to a string, ignore this function call and bail out if(0 != HIWORD( pCmdInfo->lpVerb)) return E_INVALIDARG; //Extract first icon HICON hIconLarge, hIconSmall; ExtractIconEx(m_szFile, 0, &hIconLarge, &hIconSmall, 1); ICONINFO oIconInfo; switch(LOWORD(pCmdInfo->lpVerb)) { case 0: GetIconInfo(hIconLarge, &oIconInfo); break; case 1: GetIconInfo(hIconSmall, &oIconInfo); break; default: return E_INVALIDARG; } BOOL bOpen = ::OpenClipboard(NULL); if(TRUE==bOpen) { ::EmptyClipboard(); ::SetClipboardData(CF_BITMAP, oIconInfo.hbmColor); ::CloseClipboard(); } //Destroy the icons DestroyIcon(hIconLarge); DestroyIcon(hIconSmall); return S_OK; }